package com.order.service.impl;

import java.math.BigDecimal;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONObject;
import com.order.base.mapper.BasesMapper;
import com.order.base.service.impl.BasesServiceImpl;
import com.order.config.OrderMQMsgConfig;
import com.order.mapper.OrderMapper;
import com.order.pojo.OrderInfo;
import com.order.service.OrderService;
import com.order.uitl.BaseRespons;

import lombok.extern.slf4j.Slf4j;
/**
 * @Description: 订单服务
 * @Author 徐成
 * @Date 2019/12/18 14:19
 * @Version 1.0
 */
@Service
@Slf4j
public class OrderServiceImpl 
extends BasesServiceImpl<OrderInfo> 
implements  OrderService,RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {
	@Autowired
    private   OrderMapper orderMapper;
	@Autowired
	private RabbitTemplate rabbitTemplate;
	
	@Autowired
	private RestTemplate restTemplate;
    /**
     * 创建订单
     */
    public void saveMQOrder() {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.initOrder();
        orderInfo.setAmount(new BigDecimal(100));
        orderInfo.setCustomerName("张三");
        int result = orderMapper.insert(orderInfo);
        //send mq 将订单大数据发给分单业务系统
        if (result == 1L) {
            sendMsg(orderInfo);
        }
    }

    /**
     * 创建订单
     */
    public BaseRespons saveOrder() {
    	BaseRespons b = new BaseRespons();
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.initOrder();
        orderInfo.setAmount(new BigDecimal(100));
        orderInfo.setCustomerName("张三");
        int result = orderMapper.insert(orderInfo);
        //send mq 将订单大数据发给分单业务系统
        if (result == 1L) {
        	
        	b = sendObjectHttp(orderInfo.getOrderNo());
        }else {
        	b.setState(-1);
        	b.setMsg("订单系统出错");
        }
        return b;
    }
    
    private BaseRespons sendObjectHttp(String orderNo) {
    	String url="http://localhost:8888/distribute/saveDistribute";
    	HttpHeaders headers = new HttpHeaders();
    	headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

    	MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
    	map.add("orderNo", orderNo);

    	HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);

    	ResponseEntity<BaseRespons> response = restTemplate.postForEntity( url, request , BaseRespons.class );
    	return response.getBody();
    }
    /**
     * 发送消息
     *
     * @param orderInfo
     */
    public void sendMsg(OrderInfo orderInfo) {
        rabbitTemplate.setMandatory(true);   //确认消息是否到达broker服务器
        rabbitTemplate.setConfirmCallback(this);
        String  messageJson=JSONObject.toJSONString(orderInfo);//消息序体
        
        //消息封装
        Message message = MessageBuilder.
        		withBody(messageJson.getBytes()).
        		setContentType(MessageProperties.CONTENT_TYPE_JSON).//消息类型
        		setContentEncoding("utf-8"). 
        		setMessageId(orderInfo.getOrderNo()).build();//以订单ID作为消息ID

        CorrelationData correlationData = new CorrelationData(orderInfo.getOrderNo());
        rabbitTemplate.convertAndSend(
        		OrderMQMsgConfig.EXCHANGE_NAME_TRANSACTION,//消息交换机
                OrderMQMsgConfig.ROUTE_NAME_TRANSACTION,   //路由 
                message, 
                correlationData);
         
    }
    /**
     * 用来确认消息是否有送达消息队列
     *
     * @param correlationData
     * @param ack
     * @param cause
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        log.info(JSONObject.toJSONString(correlationData));
        if (ack) {
        	System.out.println("消息发送确认成功");
        } else {
        	System.out.println("消息发送确认失败:" + cause);
        }
    }

    /**
     * 消息找不到对应的Exchange会先触发此方法
     *
     * @param message
     * @param replyCode
     * @param replyText
     * @param tempExchange
     * @param tmpRoutingKey
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String tempExchange
            , String tmpRoutingKey) {
        try {
            Thread.sleep(1000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Send message failed:" + replyCode + " " + replyText);
        rabbitTemplate.send(message);
    }

	@Override
	public BasesMapper<OrderInfo> getBasesMapper() {
		 
		return orderMapper;
	}
}
